package han.chensing.latos.maker.latos.file.util;

public class LuaParser {

    /*public static LuaTable fromLinesToLuaTable(List<Line> lines){
        LuaTable luaTable=new LuaTable();
        int key=1;
        for (Line line : lines) {
            luaTable.set(key++,transformLine(line));
        }
        return luaTable;
    }

    private static LuaTable transformLine(Line line){
        LuaTable luaTable=new LuaTable();
        luaTable.set(LuaString.valueOf("lineNum"),LuaNumber.valueOf(line.getNum()));
        LuaTable notesTable=new LuaTable();
        int key=0;
        for (Note note : line.getNotes()) {
            notesTable.set(key++,transformNote(note));
        }
        luaTable.set(LuaString.valueOf("notes"),notesTable);
        return luaTable;
    }

    private static LuaTable transformNote(Note note){
        LuaTable luaTable=new LuaTable();
        luaTable.set(LuaString.valueOf("noteType"),LuaString.valueOf(note.getNoteType().name()));
        luaTable.set(LuaString.valueOf("distanceToLineCenter"),LuaNumber.valueOf(note.getDistanceToLineCenter()));
        luaTable.set(LuaString.valueOf("bindSample"),transformSample(note.getBindSample()));
        luaTable.set(LuaString.valueOf("bindEndSample"),transformSample(note.getBindEndSample()));
        return luaTable;
    }

    private static LuaValue transformSample(Sample sample){
        if (sample==null)
            return LuaValue.NIL;
        LuaTable luaTable=new LuaTable();
        luaTable.set(LuaString.valueOf("absTime"),LuaNumber.valueOf(sample.getAbsTime()));
        luaTable.set(LuaString.valueOf("name"),LuaString.valueOf(sample.getName()));
        return luaTable;
    }

    public static TimeLine fromLuaTableToTimeLine(LuaTable luaTable){
        TimeLine timeLine=new TimeLine();
        int len = luaTable.keyCount();
        List<TimeLineRow> timeLineRows = timeLine.getTimeLineRows();
        for(int key=1;key<=len;key++){
            LuaTable childTable = luaTable.get(key).checktable();
            TimeLineRow timeLineRow=new TimeLineRow();
            timeLineRow.setHasChanged(true);
            timeLineRow.setName(childTable.get(LuaString.valueOf("name")).tojstring());
            timeLineRow.setBindLineNum(childTable.get(LuaString.valueOf("bindLineNum")).toint());
            transformToTimeLineEventSets(timeLineRow,childTable.get(LuaString.valueOf("eventSets")).checktable());
            timeLineRows.add(timeLineRow);
        }
        return timeLine;
    }

    private static void transformToTimeLineEventSets(TimeLineRow timeLineRow,LuaTable luaTable) {
        List<TimeLineEventSet> timeLineEventSets = timeLineRow.getTimeLineEventSets();
        int len = luaTable.keyCount();
        for (int key = 1; key <= len; key++) {
            LuaTable childTable = luaTable.get(key).checktable();
            TimeLineEventSet timeLineEventSet = new TimeLineEventSet(childTable.get(LuaString.valueOf("type")).toint());
            transformToTimeLineEventSet(timeLineEventSet,childTable);
            timeLineEventSets.add(timeLineEventSet);
        }
    }

    private static void transformToTimeLineEventSet(TimeLineEventSet timeLineEventSet,LuaTable luaTable){
        transformToTimeLineEvents(timeLineEventSet,luaTable.get(LuaString.valueOf("timeLineEvents")).checktable());
        transformToKeyFrames(timeLineEventSet,luaTable.get(LuaString.valueOf("keyFrames")).checktable());
    }

    private static void transformToKeyFrames(TimeLineEventSet timeLineEventSet,LuaTable luaTable){
        List<Frame> keyFrames = timeLineEventSet.getKeyFrames();
        int len=luaTable.keyCount();
        for(int key=1;key<=len;key++){
            Frame frame = transformToFrame(luaTable.get(key).checktable());
            keyFrames.add(frame);
        }
        keyFrames.sort((a,b)-> (int) ((a.getTime()-b.getTime())*1000f));
    }

    private static void transformToTimeLineEvents(TimeLineEventSet timeLineEventSet,LuaTable luaTable){
        List<TimeLineEvent> timeLineEvents = timeLineEventSet.getTimeLineEvents();
        int len = luaTable.keyCount();
        for(int key=1;key<=len;key++){
            TimeLineLineMoveEvent timeLineLineMoveEvent=new TimeLineLineMoveEvent();
            LuaTable childTable = luaTable.get(key).checktable();
            timeLineLineMoveEvent.setName(childTable.get(LuaString.valueOf("name")).tojstring());
            timeLineLineMoveEvent.setType(childTable.get(LuaString.valueOf("type")).toint());
            timeLineLineMoveEvent.setFromKeyFrame(
                    transformToFrame(childTable.get(LuaString.valueOf("fromFrame")).checktable()));
            timeLineLineMoveEvent.setToKeyFrame(
                    transformToFrame(childTable.get(LuaString.valueOf("toFrame")).checktable()));
            LineEventElement lineEventElement = timeLineLineMoveEvent.getLineEventElement();
            transformToLineEventElement(lineEventElement,childTable.get(LuaString.valueOf("lineEvent")).checktable());
            timeLineEvents.add(timeLineLineMoveEvent);
        }
        timeLineEvents.sort((a,b)->
                (int) ((a.getFromTime()-b.getFromTime())*1000f));
    }

    private static void transformToLineEventElement(LineEventElement lineEventElement,LuaTable luaTable){
        lineEventElement.setAbsTime(luaTable.get(LuaString.valueOf("absTime")).tolong());
        lineEventElement.setBindLineNum(luaTable.get(LuaString.valueOf("bindLineNum")).toint());
        lineEventElement.setEventType(EventElement.EventType.LineEvent);
        lineEventElement.setLineAnimation(transformToLineAnimation(luaTable.get(LuaString.valueOf("lineAnimation")).checktable()));
    }

    private static LineAnimation transformToLineAnimation(LuaTable luaTable){
        LineAnimation lineAnimation=new LineAnimation();
        lineAnimation.setDuration(luaTable.get(LuaString.valueOf("duration")).tofloat());
        lineAnimation.setType(luaTable.get(LuaString.valueOf("type")).toint());
        lineAnimation.setDirection(luaTable.get(LuaString.valueOf("direction")).tofloat());
        lineAnimation.setStartValue(luaTable.get(LuaString.valueOf("startValue")).tofloat());
        lineAnimation.setEndValue(luaTable.get(LuaString.valueOf("endValue")).tofloat());
        lineAnimation.setOriginStart(luaTable.get(LuaString.valueOf("originStart")).toboolean());
        lineAnimation.setOriginEnd(luaTable.get(LuaString.valueOf("originEnd")).toboolean());
        lineAnimation.setInterpolator(transformToInterpolator(luaTable.get(LuaString.valueOf("interpolator")).checktable()));
        return lineAnimation;
    }

    private static Interpolator transformToInterpolator(LuaTable luaTable){
        String type = luaTable.get(LuaString.valueOf("type")).tojstring();
        switch (type){
            case "bezier":{
                Bezier2Interpolator bezier2Interpolator=new Bezier2Interpolator();
                bezier2Interpolator.setAccuracy(luaTable.get(LuaString.valueOf("accuracy")).tofloat());
                bezier2Interpolator.setX1(luaTable.get(LuaString.valueOf("x1")).tofloat());
                bezier2Interpolator.setY1(luaTable.get(LuaString.valueOf("y1")).tofloat());
                bezier2Interpolator.setX2(luaTable.get(LuaString.valueOf("x2")).tofloat());
                bezier2Interpolator.setY2(luaTable.get(LuaString.valueOf("y2")).tofloat());
                return  bezier2Interpolator;
            }
            default:
            case "linear":
                return new LinearInterpolator();
        }
    }

    private static Frame transformToFrame(LuaTable luaTable){
        Frame frame=new Frame();
        frame.setX(luaTable.get(LuaString.valueOf("x")).tofloat());
        frame.setY(luaTable.get(LuaString.valueOf("y")).tofloat());
        frame.setSpeed(luaTable.get(LuaString.valueOf("speed")).tofloat());
        frame.setAlpha(luaTable.get(LuaString.valueOf("alpha")).tofloat());
        frame.setRotate(luaTable.get(LuaString.valueOf("rotate")).tofloat());
        frame.setEventType(luaTable.get(LuaString.valueOf("eventType")).toint());
        frame.setTime(luaTable.get(LuaString.valueOf("time")).tofloat());
        return frame;
    }

    public static LuaTable fromTimeLineToLuaTable(TimeLine timeLine){
        LuaTable luaTable=new LuaTable();
        List<TimeLineRow> timeLineRows = timeLine.getTimeLineRows();
        int key=1;
        for (TimeLineRow timeLineRow : timeLineRows) {
            luaTable.set(key++, transformTimeLineRow(timeLineRow));
        }
        return luaTable;
    }

    private static LuaTable transformTimeLineRow(TimeLineRow timeLineRow){
        LuaTable outTable=new LuaTable();
        outTable.set(
                LuaString.valueOf("bindLineNum"),
                LuaInteger.valueOf(timeLineRow.getBindLineNum()));
        outTable.set(
                LuaString.valueOf("name"),
                LuaInteger.valueOf(timeLineRow.getName()));
        LuaTable eventSetsTable=new LuaTable();
        List<TimeLineEventSet> timeLineEventSets = timeLineRow.getTimeLineEventSets();
        int key=1;
        for (TimeLineEventSet timeLineEventSet : timeLineEventSets) {
            LuaTable eventSetTable=new LuaTable();
            eventSetTable.set(LuaString.valueOf("type"),
                    LuaInteger.valueOf(timeLineEventSet.getType()));
            eventSetTable.set(
                    LuaString.valueOf("timeLineEvents"),
                    transformTimeLineEvents(timeLineEventSet));
            eventSetTable.set(
                    LuaString.valueOf("keyFrames"),
                    transformKeyFrames(timeLineEventSet)
            );
            eventSetsTable.set(key++,eventSetTable);
        }
        outTable.set(
                LuaString.valueOf("eventSets"),
                eventSetsTable);
        return outTable;
    }

    private static LuaTable transformKeyFrames(TimeLineEventSet timeLineEventSet){
        LuaTable outTable=new LuaTable();
        List<Frame> keyFrames = timeLineEventSet.getKeyFrames();
        int key=1;
        for (Frame keyFrame : keyFrames) {
            outTable.set(key++,transformFrame(keyFrame));
        }
        return outTable;
    }

    private static LuaTable transformTimeLineEvents(TimeLineEventSet timeLineEventSet){
        LuaTable outTable=new LuaTable();
        List<TimeLineEvent> timeLineEvents = timeLineEventSet.getTimeLineEvents();
        int key=1;
        for (TimeLineEvent timeLineEvent : timeLineEvents) {
            LuaTable eventTable=new LuaTable();
            eventTable.set(LuaString.valueOf("name"),LuaString.valueOf(timeLineEvent.getName()));
            eventTable.set(LuaString.valueOf("type"),LuaInteger.valueOf(timeLineEvent.getType()));
            eventTable.set(LuaString.valueOf("fromFrame"),transformFrame(timeLineEvent.getFromKeyFrame()));
            eventTable.set(LuaString.valueOf("toFrame"),transformFrame(timeLineEvent.getToKeyFrame()));
            if (timeLineEvent instanceof TimeLineLineEvent){
                TimeLineLineEvent timeLineLineMoveEvent = (TimeLineLineEvent) timeLineEvent;
                LineEventElement lineEventElement = timeLineLineMoveEvent.getLineEventElement();
                LuaTable childTable=new LuaTable();
                childTable.set(LuaString.valueOf("absTime"),LuaNumber.valueOf(lineEventElement.getAbsTime()));
                childTable.set(LuaString.valueOf("bindLineNum"),LuaNumber.valueOf(lineEventElement.getBindLineNum()));
                childTable.set(LuaString.valueOf("lineAnimation"),transformLineAnimation(lineEventElement.getLineAnimation()));
                eventTable.set(LuaString.valueOf("lineEvent"),childTable);
            }
            outTable.set(key++,eventTable);
        }
        return outTable;
    }

    private static LuaTable transformLineAnimation(LineAnimation lineAnimation){
        LuaTable outTable=new LuaTable();
        outTable.set(LuaString.valueOf("type"),LuaInteger.valueOf(lineAnimation.getType()));
        outTable.set(LuaString.valueOf("startValue"),LuaInteger.valueOf(lineAnimation.getStartValue()));
        outTable.set(LuaString.valueOf("endValue"),LuaInteger.valueOf(lineAnimation.getEndValue()));
        outTable.set(LuaString.valueOf("duration"),LuaInteger.valueOf(lineAnimation.getDuration()));
        outTable.set(LuaString.valueOf("originStart"), LuaBoolean.valueOf(lineAnimation.isOriginStart()));
        outTable.set(LuaString.valueOf("originEnd"), LuaBoolean.valueOf(lineAnimation.isOriginEnd()));
        outTable.set(LuaString.valueOf("interpolator"),transformInterpolator(lineAnimation.getInterpolator()));
        return outTable;
    }

    private static LuaTable transformInterpolator(Interpolator interpolator){
        LuaTable outTable=new LuaTable();
        String type="unknown";
        if (interpolator instanceof Bezier2Interpolator){
            Bezier2Interpolator bezier2Interpolator = (Bezier2Interpolator) interpolator;
            type="bezier";
            outTable.set(LuaString.valueOf("accuracy"),LuaNumber.valueOf(bezier2Interpolator.getAccuracy()));
            outTable.set(LuaString.valueOf("x1"),LuaNumber.valueOf(bezier2Interpolator.getX1()));
            outTable.set(LuaString.valueOf("y1"),LuaNumber.valueOf(bezier2Interpolator.getY1()));
            outTable.set(LuaString.valueOf("x2"),LuaNumber.valueOf(bezier2Interpolator.getX2()));
            outTable.set(LuaString.valueOf("y2"),LuaNumber.valueOf(bezier2Interpolator.getY2()));
        }else if (interpolator instanceof LinearInterpolator){
            type="linear";
        }
        outTable.set(LuaString.valueOf("type"),LuaString.valueOf(type));
        return outTable;
    }

    private static LuaTable transformFrame(Frame frame){
        LuaTable outTable=new LuaTable();
        outTable.set(LuaString.valueOf("x"), LuaNumber.valueOf(frame.getX()));
        outTable.set(LuaString.valueOf("y"), LuaNumber.valueOf(frame.getY()));
        outTable.set(LuaString.valueOf("rotate"), LuaNumber.valueOf(frame.getRotate()));
        outTable.set(LuaString.valueOf("speed"), LuaNumber.valueOf(frame.getSpeed()));
        outTable.set(LuaString.valueOf("alpha"), LuaNumber.valueOf(frame.getAlpha()));
        outTable.set(LuaString.valueOf("eventType"), LuaNumber.valueOf(frame.getEventType()));
        outTable.set(LuaString.valueOf("time"), LuaNumber.valueOf(frame.getTime()));
        return outTable;
    }*/
}
